package com.lambkit.db.hutool;

import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.sql.SqlBuilder;
import com.lambkit.db.*;

import java.sql.SQLException;
import java.util.List;

/**
 * @author yangyong(孤竹行)
 */
public class HutoolDbService<T extends IRowData<T>, P extends IPageData<T>> extends HutoolDbOpt<T, P> {
    private Class<T> rowClass;
    private Class<P> pageClass;

    public HutoolDbService(HutoolDb db, Class<T> rowClass, Class<P> pageClass)  {
        super(db.getDb(), db.getDialect());
        this.rowClass = rowClass;
        this.pageClass = pageClass;
    }

    @Override
    public Entity toEntity(T record) {
        Entity entity = Entity.create(record.tableName());
        entity.setFieldNames(record.columnNames());
        entity.putAll(record.toMap());
        return entity;
    }

    @Override
    public P paginate(Integer pageNumber, Integer pageSize, Sql sqlPara) {
        Page page = new Page(pageNumber, pageSize);
        try {
            SqlBuilder sqlBuilder = SqlBuilder.of(sqlPara.getSql()).addParams(sqlPara.getPara());
            int total = (int) getDb().count(sqlBuilder);
            RowPageHandler handler = new RowPageHandler<T>((Class<T>) rowClass, true, pageNumber, pageSize, total);
            return (P) getDb().page(sqlBuilder, page, handler);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<T> find(String sql, Object... paras) {
        try {
            return getDb().query(sql, new RowListHandler<T>((Class<T>) rowClass, true), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public T findFirst(String sql, Object... paras) {
        try {
            return getDb().query(sql, new RowHandler<T>((Class<T>) rowClass, true), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
